/*
 * Copyright (c) 2014 pkzd/1.0, 颜文泽(robin)
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     1 Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     2 Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include	<asm.h>
#include	<string.h>

char *
strchr(const char *s, int c)
{
	register char *p;

	for(p = s; *p; p++)
		if(*p == c)
			return p;
	return NULL;
}

char *
strncpy(char *s, char *t, size_t n)
{
	register size_t i;
	register char *p, *q;

	p = s;
	q = t;
	for(i = 0; i < n; i++){
		if((*p++ = *q++) == '\0'){
			while(++i < n)
				*p++ = '\0';
			return s;
		}
	}
	return s;
}

int
strncmp(char *s, char *t, size_t n)
{
	register size_t x;
	register char *p, *q;

	x = n;
	for(p = s, q = t; x && *p && *p == *q; p++, q++)
		--x; 
	return (x ? *p - *q : 0); 
}

char *
strncat(char *s, char *t, size_t n)
{
	register size_t x;
	register char *p, *q;

	for(p = s; *p; p++)
		;
	x = n;
	for(q = t; (*p = *q) && x; p++, q++)	
		x--;
	*p = '\0';
	return s;
}

size_t
strlen(char *s)
{
	register char *p;
	
	for(p = s; *p; p++)
		;
	return (size_t)(p - s);
}

char *
strcpy(char *s, char *t)
{
	register char *p, *q;

	for(p = s, q = t; *p = *q; p++, q++)
		;
	return s;
}

int
strcmp(char *s, char *t)
{
	register char *p, *q;

	for(p = s, q = t; *p && *p == *q; p++, q++)
		;
	return (*p - *q);
}

char *
strcat(char *s, char *t)
{
	register char *p, *q;

	for(p = s; *p; p++)
		;
	for(q = t; *p = *q; p++, q++)
		;
	return s;
}

void *
memset(void *s, int c, size_t n)
{
	if((int)s % 4 == 0 && n % 4 == 0){
		c &= 0xff;
		c = (c << 24) | (c << 16) | (c << 8) | c;
		stosl(s, c, n / 4);
	}else{
		stosb(s, c, n);
	}
}

int
memcmp(void *s, void *t, size_t n)
{
	register size_t x;
	register char *p, *q;

	x = n;
        for(p = s, q = t; x && *p == *q && *p; p++, q++)
                --x;
        return (x > 0 ? *p - *q : 0);
}

void *
memmove(void *s, void *t, size_t n)
{
	register size_t x;
	register char *p, *q;

	x = n;
	for(p = s, q = t; x; p++, q++, --x)
		*p = *q;	
	return s;
}

void *
memcpy(void *s, void *t, size_t n)
{
	return memmove(s, t, n);
}	
